package com.carrental.search.task;

import com.carrental.search.service.DataSyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 数据同步定时任务
 * 定期从各微服务同步数据到Elasticsearch
 */
@Slf4j
@Component
public class DataSyncTask {

    @Resource
    private DataSyncService dataSyncService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final String FULL_SYNC_LOCK_KEY = "car_search:data_sync:full_lock";
    private static final String INCREMENTAL_SYNC_LOCK_KEY = "car_search:data_sync:incremental_lock";
    private static final String LAST_SYNC_TIME_KEY = "car_search:data_sync:last_sync_time";

    /**
     * 全量同步车辆数据定时任务
     * 每天凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void fullSyncVehiclesTask() {
        // 使用Redis分布式锁，防止集群环境下多实例同时执行
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(FULL_SYNC_LOCK_KEY, "1", 30, TimeUnit.MINUTES);
        if (Boolean.TRUE.equals(acquired)) {
            try {
                log.info("开始执行全量同步车辆数据定时任务");
                int count = dataSyncService.syncAllVehicles();
                log.info("全量同步车辆数据定时任务执行完成，同步数据{}条", count);
                
                // 更新最后同步时间
                redisTemplate.opsForValue().set(LAST_SYNC_TIME_KEY, System.currentTimeMillis());
            } catch (Exception e) {
                log.error("全量同步车辆数据定时任务执行异常", e);
            } finally {
                // 释放锁
                redisTemplate.delete(FULL_SYNC_LOCK_KEY);
            }
        } else {
            log.info("全量同步车辆数据定时任务已在其他实例执行中");
        }
    }

    /**
     * 增量同步车辆数据定时任务
     * 每10分钟执行一次
     */
    @Scheduled(fixedRate = 600000)
    public void incrementalSyncVehiclesTask() {
        // 使用Redis分布式锁，防止集群环境下多实例同时执行
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(INCREMENTAL_SYNC_LOCK_KEY, "1", 5, TimeUnit.MINUTES);
        if (Boolean.TRUE.equals(acquired)) {
            try {
                log.info("开始执行增量同步车辆数据定时任务");
                
                // 获取上次同步时间
                Object lastSyncTimeObj = redisTemplate.opsForValue().get(LAST_SYNC_TIME_KEY);
                Long lastSyncTime = 0L;
                if (lastSyncTimeObj != null) {
                    if (lastSyncTimeObj instanceof Long) {
                        lastSyncTime = (Long) lastSyncTimeObj;
                    } else if (lastSyncTimeObj instanceof String) {
                        lastSyncTime = Long.parseLong((String) lastSyncTimeObj);
                    }
                }
                
                int count = dataSyncService.syncIncrementalVehicles(lastSyncTime);
                log.info("增量同步车辆数据定时任务执行完成，同步数据{}条", count);
                
                // 更新最后同步时间
                redisTemplate.opsForValue().set(LAST_SYNC_TIME_KEY, System.currentTimeMillis());
            } catch (Exception e) {
                log.error("增量同步车辆数据定时任务执行异常", e);
            } finally {
                // 释放锁
                redisTemplate.delete(INCREMENTAL_SYNC_LOCK_KEY);
            }
        } else {
            log.info("增量同步车辆数据定时任务已在其他实例执行中");
        }
    }

    /**
     * 同步门店位置数据定时任务
     * 每天凌晨3点执行
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void syncStoreLocationsTask() {
        log.info("开始执行同步门店位置数据定时任务");
        try {
            int count = dataSyncService.syncStoreLocations();
            log.info("同步门店位置数据定时任务执行完成，同步数据{}条", count);
        } catch (Exception e) {
            log.error("同步门店位置数据定时任务执行异常", e);
        }
    }
} 